#!/usr/bin/env bash

include "libs/ohos.sh"

#help.cmd hdc@addr2line pid addr : (仓库) 用于解析函数指针，将pid的addr转化为代码文件和行号
dynamic_cmd:hdc:addr2line()
{
    if [[ "$OHOS_HDC" =~ (ohos-sdk) ]]; then
        echo "推荐用ohos-tool cc@sdk编译出hdc_std"
    fi

    PID=$1
    ADDR=$2
    ohos:check_param PID || return
    ohos:check_param ADDR || return
    if [ "${ADDR:0:2}" != "0x" ]; then
        ADDR="0x$ADDR"
    fi

    ohos:cd_repo || return
    hdc:wait_for_device

    print:circle_slider "查询进程ID"
    if [ "$($OHOS_HDC shell ls '/proc/$PID/maps')" != "/proc/$PID/maps" ]; then
        print:circle_slider "查询进程名称"
        local result="$($OHOS_HDC shell ps -ef | grep $PID)"
        if [ "$(wc -l <<< "$result")" = "0" ]; then
            false || report "没有该进程 $PID" || return
        fi
        if [ "$(wc -l <<< "$result")" != "1" ]; then
            echo "$(cctl y)发现多个该进程 $PID，自动选择第一个$(cctl 0)"
        fi
        PID=$(head -1 <<< "$result" | awk '{print $2}')
    fi

    local filename=""
    local addr=""
    while read map; do
        local range=${map%% *}
        local offset=${map#* * }
        offset=${offset%% *}
        filename=${map##* }
        local start=${range%%-*}
        local end=${range##*-}
        if (( "0x$start" <= "$ADDR" )) && (( "$ADDR" <= "0x$end" )); then
            (( addr = $ADDR - 0x$start + 0x$offset ))
            break
        fi
    done <<< "$($OHOS_HDC shell cat /proc/$PID/maps)"

    echo "找到的地址是：$filename的0x$(printf "%x" $addr)"
    dynamic_cmd:utils:stack <<< "#00 pc $(printf "%x" $addr) $filename"
}

#help.cmd hdc@autopush [outdir] : (仓库) 用hdc自动选择推送更新后的文件, outdir默认是graphic
#alias.cmd oha : hdc@autopush
dynamic_cmd:hdc:autopush()
{
    ohos:cd_repo || return
    local tests
    tests=$(egrep '\[[0-9]+/[0-9]+\] LINK tests' ${OHOS_OUT_DIR}/build.log)
    tests=$(awk -F/ '{print $NF}' <<< $tests)
    echo "need push test: "$tests

    local other
    local outdir=graphic
    if (( $# >= 1 )); then
        outdir=$1
    fi

    other=$(egrep '\[[0-9]+/[0-9]+\] (SO)?LINK '$outdir'/' ${OHOS_OUT_DIR}/build.log)
    other=$(awk -F/ '{print $NF}' <<< $other)
    echo "need push file: "$other

    if [ ${#tests} = 0 ] && [ ${#other} = 0 ]; then
        echo "needn't push any file"
        return
    fi

    # hdc:reset
    [ "$OHOS_NORR" != "1" ] && hdc:rr
    OHOS_NORR=1

    if [ ${#other} != 0 ]; then
        local file
        while read file; do
            FILE=$file
            DIR=""
            find_push_file && hdc:push
        done <<< $other
    fi

    if [ ${#tests} != 0 ]; then
        DIR="/data/test"
        PERMISSION="755"
        dynamic_cmd:hdc:shell "mkdir -p $DIR"

        local test
        while read test; do
            FILE=$test
            find_push_file && hdc:push
        done <<< $tests
    fi
}

# dynamic.option --dir DIR : 指定一个DIR目录
# --dir.option.list: hdc@push
dynamic_option:--dir()
{
    DIR="$(arguments:get_now)"
    ohos:check_param DIR || return
    arguments:next
    return 0
}

# dynamic.option --file FILE : 指定一个FILE文件
# --file.option.list: hdc@push hdc@pull
dynamic_option:--file()
{
    FILE="$(arguments:get_now)"
    ohos:check_param FILE || return
    arguments:next
    return 0
}

# dynamic.option -norr : push不带root+remount
# -norr.option.list: hdc@push
dynamic_option:-norr()
{
    OHOS_NORR=1
    return 0
}

#help.cmd hdc@push : (仓库) 用hdc将FILE推到DIR里, 默认使用/system/lib (*.so)或/system/bin
dynamic_cmd:hdc:push()
{
    find_push_file && hdc:push
}

#help.cmd hdc@pull : (仓库) 用hdc将FILE拉到当前目录下
dynamic_cmd:hdc:pull()
{
    ohos:check_param FILE || return
    local filename="$(basename $FILE)"
    $OHOS_HDC file recv $FILE $COMMAND_CURDIR/$filename
}

#help.cmd hdc@shell : (仓库) 用hdc发送命令
dynamic_cmd:hdc:shell()
{
    hdc:wait_for_device || return
    hdc:shell $*
}

#help.cmd hdc@reset : (仓库) 重置hdc服务器
dynamic_cmd:hdc:reset()
{
    hdc:reset
}

#help.cmd hdc@rr : (仓库) root+remount
dynamic_cmd:hdc:rr()
{
    hdc:rr
}

#help.cmd hdc@v : (仓库) version
dynamic_cmd:hdc:v()
{
    hdc:version
}

#help.cmd hdc@trace : (仓库) 抓trace
dynamic_cmd:hdc:trace()
{
    dynamic_cmd:hdc:shell bytrace -t 10 -b 4096 --overwrite graphic
}

#help.cmd hdc@hilog : (仓库) 抓hilog
dynamic_cmd:hdc:hilog()
{
    dynamic_cmd:hdc:shell hilog
}

#help.cmd hdc@dump [type] [width] : (仓库) 抓dump
dynamic_cmd:hdc:dump()
{
    local dumpname="$1"
    if [ "$dumpname" = "" ]; then
        dumpname="render_"
    fi

    local width="$2"
    if [ "$width" = "" ]; then
        width=480
    fi

    local dumpdir="${dumpname}dump"
    mkdir -p $dumpdir
    cd $dumpdir
    local pwdir="$(pwd)/"
    dynamic_cmd:hdc:shell "touch /data/${dumpname}dump"
    echo "Ctrl+D结束dump"
    read
    dynamic_cmd:hdc:shell "rm /data/${dumpname}dump"
    for dump in $(hdc:shell "ls /data/${dumpname}*"); do
        $OHOS_HDC file recv $dump $pwdir
        hdc:shell "rm $dump"
        dump=$(basename $dump)

        cd $pwdir
        bytes=$(du --bytes $dump | awk '{print $1}')
        bytes=$(($bytes / 4))

        if [ $bytes = 0 ]; then
            rm $dump
            continue
        fi

        if [ $bytes = $(( 640 * 480 )) ]; then
            convert -size 640x480 -depth 8 rgba:$dump $dump.png
        else
            convert -size ${width}x$(($bytes / $width)) -depth 8 rgba:$dump $dump.png
        fi
        rm $dump
    done
}
